package com.zonski.jbots.engine.entity;


import com.zonski.jbots.engine.*;

/**
 * An entity that uses the mind interface to update its state
 */
public class MovingEntity extends Entity
{
    private MovementEffect effect;
    private Mind mind;
    private int targetVelocity;
    private int targetDirection;
    private Resource immovable;

    public Rectangle oldTileBounds;
    public Rectangle swap;

    public MovingEntity()
    {
    }

    public MovementEffect getMovementEffect()
    {
        return this.effect;
    }

    public void setMovementEffect(MovementEffect effect)
    {
        this.effect = effect;
    }

    public Mind getMind()
    {
        return this.mind;
    }

    public void setMind(Mind mind)
    {
        this.mind = mind;
    }

    public void update(Engine engine)
        throws Exception
    {
        super.update(engine);
        Resource immovable = this.immovable;
        this.mind.update(engine);

        if(this.immovable != null)
        {
            immovable = this.immovable;
        }

        if(immovable != null)
        {
            immovable.update(engine);
        }
        if(this.effect != null)
        {
            this.effect.apply(this);
        }
        RoomStateMatrix matrix = engine.getStateMatrix();
        if(this.swap == null)
        {
            this.swap = new Rectangle(0, 0, 0, 0);
        }
        Rectangle newTileBounds = matrix.convertToTileBounds(this.bounds, this.swap);
        if(!newTileBounds.equals(this.oldTileBounds))
        {
            // remove the entity from the matrix
            if(this.oldTileBounds != null)
            {
                matrix.removeEntity(
                        this, this.oldTileBounds
                );
            }
            if(!this.isRemovable())
            {
                // add the entity to the matrix
                matrix.addEntity(this, newTileBounds);
                this.swap = this.oldTileBounds;
                this.oldTileBounds = newTileBounds;
            }
            else if(this.oldTileBounds == null)
            {
                // get rid of it any way you can
                matrix.removeEntity(this);
                System.out.println("warning : inefficient remove");
            }
        }else if(isRemovable()){
            if(this.oldTileBounds != null)
            {
                matrix.removeEntity(
                        this, this.oldTileBounds
                );
            }else{
                // get rid of it any way you can
                matrix.removeEntity(this);
                System.out.println("warning : inefficient remove");
            }
        }
    }

    public boolean collision(Engine engine, CollisionData data)
    {
        boolean b = super.collision(engine, data);
        this.mind.collision(engine, data);
        return b;
    }

    public int getTargetDirection()
    {
        return this.targetDirection;
    }

    public void setTargetDirection(int targetDirection)
    {
        this.targetDirection = targetDirection;
    }

    public int getTargetVelocity()
    {
        return this.targetVelocity;
    }

    public void setTargetVelocity(int targetVelocity)
    {
        this.targetVelocity = targetVelocity;
    }

    public void allowMovement(Resource immovable)
    {
        if(this.immovable == immovable)
        {
            this.immovable = null;
        }
    }

    public void stopMovement(Resource immovable)
    {
        this.immovable = immovable;
    }

    public boolean isMovable()
    {
        return this.immovable == null;
    }
}
